package com.sinosoft.web.easyui.api;

import cn.com.sinux.spring.utils.QueryHelper;
import com.google.code.kaptcha.Constants;
import com.sinosoft.hydra.um.LoginUser;
import cn.com.sinux.spring.commons.SystemConfig;
import com.sinosoft.hydra.um.condition.*;
import com.sinosoft.hydra.um.constant.BaseConstant;
import com.sinosoft.hydra.um.domain.permission.*;
import cn.com.sinux.spring.exception.ServiceException;
import com.sinosoft.hydra.um.helper.AuthContextHelper;
import com.sinosoft.hydra.um.helper.LoggerHelper;
import com.sinosoft.hydra.um.services.*;
import com.sinosoft.hydra.um.utils.AppUtils;
import cn.com.sinux.spring.utils.JsonUtils;
import cn.com.sinux.spring.utils.PageUtils;
import cn.com.sinux.spring.utils.ValidatorUtils;;
import com.sinosoft.web.common.SessionBindListener;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("api/home")
public class SysHomeApi {
    /**
     * 系统用户服务类
     */
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysOrganizationService sysOrganizationService;
    @Autowired
    private DocumentService documentService;
    @Autowired
    private DirectoryService directoryService;
    @Autowired
    private AttendanceService attendanceService;
    @Autowired
    private SysEBomService sysEBomService;
    @Autowired
    private SysPBomService sysPBomService;
    @Autowired
    private SysBestService sysBestService;

    /**
     * 加密设置服务类
     */
    @Autowired
    private SysUserSecurityTypeService sysUserSecurityTypeService;

    /**
     * 登录
     *
     * @param loginUrl      登陆页面相当于pages的路径  必填
     * @param indexUrl      登录成功页面相当于pages的路径  必填
     * @param user          用户名和密码  必填
     * @param rememberMe    是否记住我；0：不记住；1：记住我；默认值为0
     * @param captcha_value 验证码  必填
     * @param model
     * @return String 页面名称
     */
    @RequestMapping(value = "logining")
    public String login(@RequestParam(required = true) String loginUrl,
                        @RequestParam(required = true) String indexUrl, SysUserMember user,
                        @RequestParam(defaultValue = "0", required = false) String rememberMe,
                        @RequestParam(value = "kaptcha", required = false) String captcha_value,
                        HttpServletRequest request, HttpServletResponse response, Model model) {
        HttpSession session = request.getSession(true);
        int loginCount = 0;
        if (session.getAttribute("login_err") == null) {
            session.setAttribute("login_err", loginCount);
            session.setAttribute("login_time", new Date());
            session.setMaxInactiveInterval(30 * 60 * 1000);
        } else {
            loginCount = (Integer) session.getAttribute("login_err");
            if (loginCount >= 10) {
                Date date = (Date) session.getAttribute("login_time");
                long times = 30 - ((new Date().getTime() - date.getTime()) % (1000 * 60 * 60)) / (1000 * 60);
                model.addAttribute("user_err", MessageFormat.format("尝试次数过多，请等{0}分钟后再试！", times));
                return loginUrl;
            }
        }
        if (SystemConfig.getBooleanProperty("use.validate.code")) {
            if (session.getAttribute(Constants.KAPTCHA_SESSION_KEY) == null) {
                throw new ServiceException("页面过期！");
            }
            String kaptchaExpected = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
            String kaptchaReceived = captcha_value;
            if (!org.apache.commons.lang.StringUtils.isNotBlank(kaptchaExpected) || !kaptchaReceived.equals(kaptchaExpected)) {
                session.setAttribute("login_err", ++loginCount);
                model.addAttribute("user_err", "验证码错误！");
                session.setAttribute("login_time", new Date());
                return loginUrl;
            }
        }

        if (user.getUserNumber() == null || user.getUserNumber().trim().equals("") || user.getUserPassword().trim().equals("") || user.getUserPassword() == null) {
            model.addAttribute("user_err", setMessageForLogin(session, loginCount) + "登陆失败:(用户名或者密码不能为空!)");
            return loginUrl;
        }
        SysUserMember um = sysUserService.doGetAuthenticationInfoByNumber(user.getUserNumber());
        if (um != null && BaseConstant.INTEGER_TRUE.equals(um.getAvailable())) {
//            if (!SystemConfig.getBooleanProperty("sync.work.enable") && ValidatorUtils.isArrayEmpty(um.getSysOrganizations())) {
//                model.addAttribute("user_err", setMessageForLogin(session, loginCount) + "登陆失败:(用户还没有分配部门!)");
//                return loginUrl;
//            }
            String password = "";
            SysUserSecurityType sysUserSecurityType = sysUserSecurityTypeService.getSysUserSecurityType();
            if (sysUserSecurityType != null) {
                if (sysUserSecurityType.getSecurityType().equals("1")) {//32
                    password = AppUtils.GetMD5(user.getUserPassword() + um.getUserSalt(), 32, "MD5");
                } else if (sysUserSecurityType.getSecurityType().equals("2")) {//40
                    password = AppUtils.GetMD5(user.getUserPassword() + um.getUserSalt(), 32, "SHA-1");
                } else if (sysUserSecurityType.getSecurityType().equals("3")) {//64
                    password = AppUtils.GetMD5(user.getUserPassword() + um.getUserSalt(), 32, "SHA-256");
                }
            } else {
                password = AppUtils.GetMD5(user.getUserPassword() + um.getUserSalt(), 32, "MD5");
            }
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserNumber(), password, !"0".equals(rememberMe));
            Subject currentUser = AppUtils.getSubject();
            try {
                currentUser.login(token);
                if (currentUser.isAuthenticated()) {
                    session.setAttribute("LOGIN_FLAG", true);
                    currentUser.isPermitted("-1");//强制授权
                    AuthContextHelper.setLoginUser(AppUtils.createLoginUser(request, response));
                    session.setAttribute("sessionListener", new SessionBindListener());
//                    LoggerHelper.logInfo("成功登录了系统");
                    return indexUrl;//indexUrl;
                } else {
                    model.addAttribute("user_err", setMessageForLogin(session, loginCount) + "登陆失败:(请检查您的用户名和密码是否正确!)");
                    return loginUrl;
                }
            } catch (AuthenticationException e) {
                token.clear();
                model.addAttribute("user_err", setMessageForLogin(session, loginCount) + "登陆失败:(请检查您的用户名和密码是否正确!)");
                return loginUrl;
            }
        } else {
            model.addAttribute("user_err", setMessageForLogin(session, loginCount) + "登陆失败:" + (um != null && BaseConstant.INTEGER_FALSE.equals(um.getAvailable()) ? "(用户已被禁用,请联系管理员!)" : "(用户不存在!)"));
            return loginUrl;
        }
    }

    @RequestMapping(value = "ipLogin")
    public String ipLogin(@RequestParam(required = true) String loginUrl,
                        @RequestParam(required = true) String indexUrl,
                        HttpServletRequest request, HttpServletResponse response, Model model){
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
        HttpSession session = request.getSession(true);
        SysUserMember user = sysUserService.findByIp(ip);
        if (user != null && BaseConstant.INTEGER_TRUE.equals(user.getAvailable())){
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserNumber(), user.getUserPassword(), false);
            Subject currentUser = AppUtils.getSubject();
            currentUser.login(token);
            session.setAttribute("LOGIN_FLAG", true);
            currentUser.isPermitted("-1");//强制授权
            AuthContextHelper.setLoginUser(AppUtils.createLoginUser(request, response));
            session.setAttribute("sessionListener", new SessionBindListener());
//            LoggerHelper.logInfo("成功登录了系统");
            return indexUrl;
        }else {
            model.addAttribute("user_err", "登陆失败:" + (user != null && BaseConstant.INTEGER_FALSE.equals(user.getAvailable()) ? "(用户已被禁用,请联系管理员!)" : "(用户IP地址不存在!)"));
            return loginUrl;
        }
    }

    private String setMessageForLogin(HttpSession session, int loginCount) {
        session.setAttribute("login_err", ++loginCount);
        session.setAttribute("login_time", new Date());
        int num = SystemConfig.getIntegerProperty("max.error.login", 10);
        if (loginCount >= num) {
            return "剩余登录次数0次，请30分钟后重试！";
        }
        return "剩余登录次数" + (num - loginCount) + "次，";
    }

//    @RequestMapping(value = "index")
//    public String gotoIndex(Model model, LoginUser loginUser) {
//        Page<SysOrganization> organizations = sysOrganizationService.findAll(new SearchOrganizationCondition(), PageUtils.buildPageRequest(1,1));
//        Page<SysUserMember> userMembers = sysUserService.findAllByPage(PageUtils.buildPageRequest(1, 1), null);
//        Page<TDocumentCopy> documents = documentService.findDocuments(new SearchDocumentCondition(), PageUtils.buildPageRequest(1, 1));
//        Page<TDocumentCopy> myDocuments = documentService.findMyDocuments(new SearchDocumentCondition(), loginUser, PageUtils.buildPageRequest(1, 1));
//        SearchEBomCondition searchEBomCondition = new SearchEBomCondition();
//        SearchPBomCondition searchPBomCondition = new SearchPBomCondition();
//        searchEBomCondition.setRoot(true);
//        searchPBomCondition.setRoot(true);
//        Page<TEBom> teBoms = sysEBomService.findEBoms(searchEBomCondition, PageUtils.buildPageRequest(1, 1));
//        Page<TPBom> tpBoms = sysPBomService.findPBoms(searchPBomCondition, PageUtils.buildPageRequest(1, 1));
//        Page<TBestProcess> bestProcesses = sysBestService.findBestProcess(new SearchBestProcessCondition(), PageUtils.buildPageRequest(1, 1));
//
//        model.addAttribute("online", AppUtils.OnlineCounter.INSTANCE.getOnline());
//        model.addAttribute("orgTotal", organizations.getTotalElements());
//        model.addAttribute("userTotal", userMembers.getTotalElements());
//        model.addAttribute("bestTotal", bestProcesses.getTotalElements());
//        model.addAttribute("documentTotal", documents.getTotalElements());
//        model.addAttribute("myDocumentTotal", myDocuments.getTotalElements());
//        model.addAttribute("ebomTotal", teBoms.getTotalElements());
//        model.addAttribute("pbomTotal", tpBoms.getTotalElements());
//        return "hydra_easyui/home";
//    }

//    @RequestMapping(value = "index")
//    public String gotoIndex(Model model, LoginUser loginUser) {
//        SearchOrganizationCondition orgCondition = new SearchOrganizationCondition();
//        orgCondition.setAvailable(1);
//        List<SysOrganization> orgList = sysOrganizationService.findAll(orgCondition, null).getContent();
//        List<List<SysUserMember>> colList = new LinkedList<List<SysUserMember>>();
//        int colSum = 0;
//        for (SysOrganization organization : orgList) {
//            SearchUserCondition userCondition = new SearchUserCondition();
//            userCondition.setOrgId(organization.getId());
//            List<SysUserMember> userList = sysUserService.findAllByPage(null, userCondition).getContent();
//            userList.get(userList.size()-1).setUserSalt("last");
//            colList.add(userList);
//            if (colSum < userList.size()){
//                colSum = userList.size();
//            }
//        }
//        List<List<SysUserMember>> rowList = new LinkedList<List<SysUserMember>>();
//        for (int i = 0; i < colSum; i++) {
//            List<SysUserMember> row = new LinkedList<SysUserMember>();
//            for (List<SysUserMember> col : colList) {
//                if (i <= col.size() - 1){
//                    row.add(col.get(i));
//                }else {
//                    row.add(null);
//                }
//            }
//            rowList.add(row);
//        }
//
//        SearchAttendanceCondition condition = new SearchAttendanceCondition();
//        condition.setHome(true);
//
//        final TDirectory business = directoryService.findDirectories("DIRECTORY_REASON_TYPE","公干");
//        condition.setReason(business);
//        final List<TAttendance> businessList = attendanceService.findAll(condition, null).getContent();
//
//        TDirectory overWork = directoryService.findDirectories("DIRECTORY_REASON_TYPE","加班");
//        condition.setReason(overWork);
//        final List<TAttendance> overWorkList = attendanceService.findAll(condition, null).getContent();
//
//        condition.setReason(null);
//        final List<TAttendance> allList = attendanceService.findAll(condition, null).getContent();
//        List<TAttendance> holidayList = QueryHelper.doFilter(allList, new QueryHelper.MatchWorker<TAttendance>() {
//
//            public boolean match(TAttendance attendance) {
//                return (!businessList.contains(attendance)) && (!overWorkList.contains(attendance));
//            }
//        });
//
//        for (List<SysUserMember> row : rowList) {
//            for (SysUserMember userMember : row) {
//                if (userMember != null){
//                    userMember.setAlias(null);
//                    for (TAttendance attendance : businessList) {
//                        if (attendance.getApplyUser().getId().equals(userMember.getId())){
//                            userMember.setAvailable(9);
//                            userMember.setAlias(attendance.getRemark());
//                        }
//                    }
//                    for (TAttendance attendance : holidayList) {
//                        if (attendance.getApplyUser().getId().equals(userMember.getId())){
//                            userMember.setAvailable(7);
//                            userMember.setAlias(attendance.getReason().getDirValue() + ":" + attendance.getRemark());
//                        }
//                    }
//                }
//            }
//        }
//
//        model.addAttribute("orgList", orgList);
//        model.addAttribute("rowList", rowList);
//        return "hydra_easyui/home";
//    }

    @RequestMapping(value = "index")
    public String gotoIndex(Model model, LoginUser loginUser) {

        SearchAttendanceCondition condition = new SearchAttendanceCondition();
        condition.setHome(true);

//        final TDirectory business = directoryService.findDirectories("DIRECTORY_REASON_TYPE","公干");
//        condition.setReason(business);
//        final List<TAttendance> businessList = attendanceService.findAll(condition, null).getContent();
//
//        TDirectory overWork = directoryService.findDirectories("DIRECTORY_REASON_TYPE","加班");
//        condition.setReason(overWork);
//        final List<TAttendance> overWorkList = attendanceService.findAll(condition, null).getContent();
//
//        condition.setReason(null);
//        final List<TAttendance> allList = attendanceService.findAll(condition, null).getContent();
//        List<TAttendance> holidayList = QueryHelper.doFilter(allList, new QueryHelper.MatchWorker<TAttendance>() {
//
//            public boolean match(TAttendance attendance) {
//                return (!businessList.contains(attendance)) && (!overWorkList.contains(attendance));
//            }
//        });

        List<TAttendance> list = attendanceService.findAll(condition, null).getContent();
        List<TAttendance> businessList = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

            public boolean match(TAttendance attendance) {
                String reason = attendance.getReason().getDirValue();
                return ("公干".equals(reason)) || ("出差".equals(reason));
            }
        });
        List<TAttendance> holidayList = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

            public boolean match(TAttendance attendance) {
                String reason = attendance.getReason().getDirValue();
                return (!"加班".equals(reason)) && (!"公干".equals(reason)) && (!"出差".equals(reason));
            }
        });

        SearchOrganizationCondition orgCondition = new SearchOrganizationCondition();
        orgCondition.setAvailable(1);
        List<SysOrganization> orgList = sysOrganizationService.findAll(orgCondition, null).getContent();
        Map<String, List<SysUserMember>> map = new LinkedHashMap<String, List<SysUserMember>>();
        for (SysOrganization organization : orgList) {
            SearchUserCondition userCondition = new SearchUserCondition();
            userCondition.setAvailable(1);
            userCondition.setOrgId(organization.getId());
            Pageable page = PageUtils.buildPageRequest(1, 999, "userNumber",  "asc");
            List<SysUserMember> userList = sysUserService.findAllByPage(page, userCondition).getContent();
            for (SysUserMember user : userList) {
                user.setAlias(null);
                SimpleDateFormat sdf = new SimpleDateFormat("M月dd日HH:mm");
                for (TAttendance attendance : businessList) {
                    if (attendance.getApplyUser().getId().equals(user.getId())){
                        if("公干".equals(attendance.getReason().getDirValue())){
                            user.setAvailable(9);
                        }else {
                            user.setAvailable(11);
                        }
                        String title = sdf.format(attendance.getBeginTime());
                        if (attendance.getEndTime() != null){
                            title += "~" + sdf.format(attendance.getEndTime());
                        }
                        title += "  " + attendance.getReason().getDirValue() + "\n" + attendance.getRemark();
                        user.setAlias(title);
                    }
                }
                for (TAttendance attendance : holidayList) {
                    if (attendance.getApplyUser().getId().equals(user.getId())){
                        user.setAvailable(7);
                        String title = sdf.format(attendance.getBeginTime());
                        if (attendance.getEndTime() != null){
                            title += "~" + sdf.format(attendance.getEndTime());
                        }
                        title += "  " + attendance.getReason().getDirValue() + "\n" + attendance.getRemark();
                        user.setAlias(title);
                    }
                }
            }
            map.put(organization.getOrgName(), userList);
        }

        model.addAttribute("map", map);
        return "hydra_easyui/home";
    }

    @RequestMapping(value = "num")
    @ResponseBody
    public String messageTotals(Model model, LoginUser loginUser) {
        Page<TDocumentCopy> myDocuments = documentService.findMyDocuments(new SearchDocumentCondition(), loginUser, PageUtils.buildPageRequest(1, 1));
        model.addAttribute("myDocumentTotal", myDocuments.getTotalElements());
        return "hydra_easyui/home";
    }

    /**
     * 页面跳转
     *
     * @return 跳转制定也
     */
    @RequestMapping("redirectIndex")
    public String redirectIndex() {
        return "hydra_easyui/login";
    }


    /**
     * 页面跳转
     *
     * @return 跳转制定也
     */
    @RequestMapping("redirectWait")
    public String redirectWait(@RequestParam(value = "d", required = false) String d) {
        return "hydra_easyui/wait";
    }


    /**
     * 用户登出系统
     *
     * @return 登出返回首页
     */
    @RequestMapping("loginOut")
    public String loginOut() {
        AppUtils.logout();
//        LoggerHelper.logInfo("登出了系统");
        return "redirect:redirectIndex";
    }


    /**
     * 修改logo图标
     *
     * @param logoFile logo图标地址
     * @return 修改结果
     */
    @RequestMapping(value = "uploadLogo")
    @RequiresPermissions(value = "logo:data:update")
    @ResponseBody
    public Object addMerchant(@RequestParam(value = "logoFileWeb", required = false) MultipartFile logoFile) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.TEXT_PLAIN);
        LoggerHelper.logInfo("修改了系统给的logo");
        return new ResponseEntity<String>(JsonUtils.objectToJsonString(Collections.singletonMap("flag", true)), headers, HttpStatus.OK);
    }

    @RequestMapping(value = "logReport4Index")
    public String logReport4Index(Model model) {
        return "hydra_easyui/indexModule/indexLogReport";
    }
}
